package controller;

/* Action for Sending Specific survey to respondents*/
import helper.UserType;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.UUID;


import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import model.MailingListDAO;
import model.MailingListDataDAO;
import model.Model;
import model.Sid_RespondentDAO;
import model.UserDAO;
import model.SurveyDAO;

import org.mybeans.dao.DAOException;
import org.mybeans.form.FormBeanException;
import org.mybeans.form.FormBeanFactory;

import databeans.MailingList;
import databeans.MailingListData;
import databeans.Sid_Respondent;
import databeans.Survey;
import databeans.User;

import formbeans.SendSurveyForm;

public class SendSurveyAction extends Action {
	private FormBeanFactory<SendSurveyForm> formBeanFactory = FormBeanFactory.getInstance(SendSurveyForm.class);
	private UserDAO userDAO;
	private SurveyDAO surveyDAO;
	private Sid_RespondentDAO srDAO;
	private MailingListDAO mlDAO;
	private MailingListDataDAO mldDAO;
	// The domain name of the website
	final String domainName = "localhost:";
	public SendSurveyAction(Model model) {
		userDAO = model.getUserDAO();
		surveyDAO = model.getSurveyDAO();
		srDAO = model.getSid_RespondentDAO();
		mlDAO = model.getMailingListDAO();
		mldDAO = model.getMailingListDataDAO();
	}
	
	public String getName() {
		return "sendsurvey.do";
	}

	public String perform(HttpServletRequest request) {
		
		List<String> errors = new ArrayList<String>();
		request.setAttribute("errors",errors);
		
		try {	
			//check if user is researcher
			HttpSession session = request.getSession(false);
			User user = (User) session.getAttribute("user");
			Survey survey = (Survey) session.getAttribute("survey");
			
			if(user.getType() != UserType.RESEARCHER) {
				errors.add("You are not a researcher!");
				return "homepage.jsp";
			}
			
			if (survey == null) {
				errors.add("Invalid survey!");
				return "homepage.jsp";
			}
			
			
			
			String button = request.getParameter("button");
			
			if(button == null)
				return "homePage.jsp";
			
			if (button.equals("Send to mailing list")) {
				synchronized(session) {
					session.setAttribute("sendsurvey", "mailinglist");
				}
				return "sendsurvey.jsp";
			}
			
			if (button.equals("Send to individual respondents")) {
				synchronized(session) {
					session.setAttribute("sendsurvey", "individual");
				}
				return "sendsurvey.jsp";
			}
			
			if(button.equals("Back") || button.equals("Go Back to View Survey")){
				try {
					Survey[] old_survey = (Survey[]) surveyDAO.getUserSurveys(user.getUserid());
					synchronized(session) {
						session.setAttribute("surveylist", old_survey);
						session.setAttribute("sendsurvey", null);
					}
    			} catch (DAOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
    			}
				return "viewsurvey.jsp";
			}
			

			//-------- DEBUG MODE (marks survey as sent without actually sending it via email) ------------//
			if (button.equals("Send (debug mode)")) {
				SendSurveyForm form = formBeanFactory.create(request);
				request.setAttribute("sendsurveyform", form);
				
				if(!form.isPresent()) {
					return "sendsurvey.jsp";
				}
				// Only make a new respondent type user if it is not already made
				User resp = userDAO.lookup(form.getUserid());
				if (resp == null) {
					resp = new User(form.getUserid());
					resp.setPassword(randomPassword(6));
					resp.setType(UserType.RESPONDENT);
					userDAO.create(resp);
				}
				
				// Make a new sid_respondent entry
				Sid_Respondent newSr = new Sid_Respondent(survey.getSid(), resp.getUserid());
				if (srDAO.lookup(newSr.getSid(), newSr.getRespid()) == null) {
					newSr.setCompleted(0);
					srDAO.create(newSr, surveyDAO, userDAO);
				}
				
				// Update that survey has been flagged as sent
				if (survey.getSent() == 0) {
					survey.setSent(1);
					surveyDAO.updateSubmitted(survey);
					synchronized(session) {
						session.setAttribute("survey", survey);
					}
				}
				return "sendrespondent.jsp";
			}
			//-------------------------------//
			if(button.equals("Send")||button.equals("Send to more users")) {
				String sendsurvey = (String) session.getAttribute("sendsurvey");
				System.out.println("hihi");
				
				if (sendsurvey.equals("individual")) { // Sending to individuals
					SendSurveyForm form = formBeanFactory.create(request);
					request.setAttribute("sendsurveyform", form);
					
					if(!form.isPresent()) {
						return "sendsurvey.jsp";
					}
					errors.addAll(form.checkSendSurveyFormErrors());
					if(errors.size() != 0){
						request.setAttribute("errors", errors);
						System.out.println(errors);
						return "sendsurvey.jsp";
					}
					// Only make a new respondent type user if it is not already made
					User resp = userDAO.lookup(form.getUserid());
					if (resp == null) {
						resp = new User(form.getUserid());
						resp.setPassword(randomPassword(6));
						resp.setType(UserType.RESPONDENT);
						userDAO.create(resp);
					}
					send(request, resp, form.getEmail());
				}
				else { // Send via mailing list
					MailingList ml = mlDAO.getMailingListByUseridName(user.getUserid(), survey.getMailinglist());
					MailingListData[] mldlist = mldDAO.getMailingListDataByMlid(ml.getMlid());

					for (int i = 0; i < mldlist.length; i++) {
						User resp = userDAO.lookup(mldlist[i].getRespid());
						send(request, resp, mldlist[i].getEmail());
					}
				}
				
				return "sendrespondent.jsp";
			}
		} catch(DAOException e) {
			if(e.getMessage().equals("registered"))
				errors.add("");
			return "sendrespondent.jsp";
		} catch(FormBeanException e) {
			errors.add(e.getMessage());
			return "sendsurvey.jsp";
		}
		return "sendsurvey.jsp";
	}
	
	private void send(HttpServletRequest request, User resp, String email) throws DAOException {
		HttpSession session = request.getSession();
		Survey survey = (Survey) session.getAttribute("survey");
		
		// make a Web_link 
		String webLink = "128.237.124.161" + ":" + request.getLocalPort() + request.getContextPath()+"/login.do?";
		String web_link = makeWebLink(resp,survey,webLink);

		System.out.println("the link is " + web_link);
		
		// Make a new sid_respondent entry
		Sid_Respondent sr = new Sid_Respondent(survey.getSid(), resp.getUserid());
		sr.setCompleted(0);
		srDAO.create(sr, surveyDAO, userDAO);
		
		// Update that survey has been flagged as sent
		if (survey.getSent() == 0) {
			survey.setSent(1);
			surveyDAO.updateSubmitted(survey);
			synchronized(session) {
				session.setAttribute("survey", survey);
			}
		}
		
		// send the email to according to the email address
		Properties props = System.getProperties();
		props.put("mail.smtp.host", "smtp.gmail.com");
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.starttls.enable","true");
		
		String sender = "casos.ims@gmail.com";
		String password = "casos-ims";
		//MyAuthenticator myauth = new MyAuthenticator(sender,password);
		Session session1 = Session.getInstance(props, new javax.mail.Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication("casos.ims@gmail.com", "casos-ims");
			}
		});
		String receiver = email;
		String subject = (String) request.getParameter("subject");
		String sender_message = (String) request.getParameter("emailmessage");
		sender_message = sender_message.replace("[webLink]",web_link);
		System.out.println("the message is " + sender_message);
		//sender_message = sender_message + "<br>" + resp.getUserid() + "<br>" + resp.getPassword();
		try {
			Message message = new MimeMessage(session1);
			message.setFrom(new InternetAddress(sender));
			message.setRecipients(Message.RecipientType.TO,InternetAddress.parse(receiver));
			message.setSubject(subject);
			if(message!=null) message.setText(sender_message + "\nPlease note that your username is " + resp.getUserid() + " and your password is " + resp.getPassword());
			Transport transport = session1.getTransport("smtp");
			transport.connect("smtp.gmail.com", 587, sender, password);
			Transport.send(message);
			System.out.println("done!");
		} catch (AddressException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private String randomPassword(int length) {
		String uuid = UUID.randomUUID().toString().substring(0,length);	  
		return uuid;
	}
	
	private synchronized String makeWebLink(User resp, Survey survey,String webLink ){
		// get hashed password
		String hashPassword = resp.getHashedPassword();
		// get survey id
		String surveyId = Integer.toString(survey.getSid());
		String link = "http://"+ webLink + "q=" + resp.getUserid() + "&" + "p=" + hashPassword + "&" + "id=" + surveyId; 
		return link;
	}
}

